// MazeBot.cpp : Defines the entry point for the DLL application.
//

#include "Level.h"
#include "Line.h"
#include <Clarity/Math/Math.h>
#include <Clarity/Math/Ray2.h>


namespace
{
}

Level::Level(const AARect &bounds,const AgentInitData &agentInitData)
   : m_bounds(bounds), m_agentInitData(agentInitData)
{
	//m_Line = new Lines(m_agentInitData.sceneManager);
}

void Level::AddWall(const AARect &wall)
{
   m_wall.push_back(wall);
}


bool Level::Intersects(const Vector2 &position) const
{
   // Anywhere outside the bounds is classes as an intersection
   if (!Clarity::Intersects(m_bounds, position))
   {
      return true;
   }

   // Test against each wall
   std::vector<AARect>::const_iterator it;
   std::vector<AARect>::const_iterator itEnd = m_wall.end();

   for (it = m_wall.begin(); it != itEnd; ++it)
   {
      const AARect &rect = *it;

      if (Clarity::Intersects(rect, position))
      {
         return true;
      }
   }

   return false;
}

bool Level::Intersects(const Circle &circle) const
{
   std::vector<AARect>::const_iterator it;
   std::vector<AARect>::const_iterator itEnd = m_wall.end();

   for (it = m_wall.begin(); it != itEnd; ++it)
   {
      const AARect &rect = *it;

      if (Clarity::Intersects(rect, circle))
      {
         return true;
      }
   }

   return false;
}

bool Level::IsPathBetween(const Vector2 &position1, const Vector2 &position2, float radius) const
{
   Vector2 from1To2Dir = position2 - position1;
   float from1To2Dist = from1To2Dir.Normalise();

   Vector2 from1To2Norm = Vector2(from1To2Dir.y, -from1To2Dir.x);
   Vector2 edgePos = from1To2Norm * radius;

   Ray2 ray1(position1 + edgePos, from1To2Dir);
   Ray2 ray2(position1 - edgePos, from1To2Dir);

   float localCost;

   if (
      IsLineOfSightClear(ray1, from1To2Dist, localCost) &&
      IsLineOfSightClear(ray2, from1To2Dist, localCost))
   {
	   //m_Line->addLine(position1,position2,0,0,255);
      return true;
   }

   return false;
}

bool Level::IsLineOfSightClear(const Ray2 &ray, float maxDistance, float &cost) const
{
   std::vector<AARect>::const_iterator it;
   std::vector<AARect>::const_iterator itEnd = m_wall.end();

   for (it = m_wall.begin(); it != itEnd; ++it)
   {
      const AARect &rect = *it;
      float distance;

      if (Clarity::Intersects(rect, ray, &distance) && distance <= maxDistance)
      {
         return false;
      }
   }

   return true;
}
